package toy.keli.edic.ui.home.homescreen

import android.annotation.SuppressLint
import android.content.Context
import android.os.Handler
import android.util.Log
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.calculatePan
import androidx.compose.foundation.gestures.detectTransformGestures
import androidx.compose.foundation.gestures.forEachGesture
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.NestedScrollDispatcher
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import androidx.compose.ui.input.pointer.PointerInputChange
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import toy.keli.edic.data.config.MenuConf.mode.showArticle
import toy.keli.edic.data.config.MenuConf.mode.wordStudy
import toy.keli.edic.data.config.PageConf
import toy.keli.edic.ui.bindkeyBoradEvent
import toy.keli.edic.ui.bookmark.components.BookSearch
import toy.keli.edic.ui.home.HomeEvents
import toy.keli.edic.ui.home.TAG
import toy.keli.edic.ui.home.components.AutoCompleteTextField
import toy.keli.edic.ui.home.viewMode
import toy.keli.edic.ui.main.components.Display.px2dp
import toy.keli.edic.util.ActivityRun
import kotlin.math.abs

@SuppressLint("RememberReturnType")
@Composable
fun SlidingEnable(enabled:Boolean,contentBox: @Composable BoxScope.() -> Unit) {
    val ct = LocalContext.current
    val data = remember {  SlidingEnableData(ct,enabled) }
    data.apply {
        //当前拖拽的值修改事件 包括停止拖拽之后值得动态效果
        LaunchedEffect(key1 = dragDistance) {
            val absDragHeight = abs(dragDistance)
            if (absDragHeight > limitHight && !(true in tryShowPageVisables)) {
                upPageIndex()
                showLoadingPage = false
            }
        }
        Box(
            modifier = Modifier
                .fillMaxSize()
                //获取点输入事件
                .pointerInput(Unit) {
                    //手指松开事件
                    forEachGesture {
                        awaitPointerEventScope {
                            awaitFirstDown(false)
                            var mvPos = Offset.Zero
                            val minMove = 20;
                            var points:List<PointerInputChange>
                            do {
                                val event = awaitPointerEvent()
                                val pan = event.calculatePan()
                                points = event.changes

                                mvPos += pan
                                if (abs(mvPos.y) < abs(mvPos.x) * 2) continue

                                //总开关可上下滑动 子元素的下滑距离已经用完 还没有开启滑动 并且向下或向上移动了一段距离了 左右滑动没有开启
                                if (HomeEvents.status.enableDrowUp
                                    && HomeEvents.status.openDrowUp
                                    && !HomeEvents.downMenuOpen
                                    && !dragEnabled.value
//                                    && (points.size == 2 || HomeEvents.status.openDrowUp)
                                    && ((showPageIndex == 1 && mvPos.y > minMove) || (showPageIndex == 0 && mvPos.y < -minMove))
                                    //&& ((mvPos.y > minMove || mvPos.y < -minMove))
                                    && !HomeEvents.status.openDrowX
                                ) {
                                    //if (mvPos.y > minMove && !HomeEvents.onDragDownBefore()) {
                                    //     return@awaitPointerEventScope
                                    //}
                                    dragEnabled.value = true
                                    Log.d(TAG, "SlidingEnable: open")
                                }
                                //没有开启滑动 向上滑动了一段距离了 上拉尝试弹出底部菜单
                                if (!dragEnabled.value && HomeEvents.status.enableDrowDown && (showPageIndex == 1 && mvPos.y < -200)) {
                                    if(2 == PageConf.homePage.ShowMenuEvent.getValue()) {
                                        HomeEvents.onOpenMenu(mvPos)
                                    }
                                }
                                //if (!dragEnabled.value && (points.size == 2 || HomeEvents.status.openDrowUp) && (showPageIndex == 1 && mvPos.y < -200)) {
                                //    HomeEvents.onDragUp()
                                //}
                                if (dragEnabled.value) {
                                    onDelta(pan.y)
                                }else if(HomeEvents.status.enableDrowX && !HomeEvents.downMenuOpen){ //左右的距离大于上下的距离2倍了 并且也超过了最小距离后按照左右滑动处理
                                    if(!HomeEvents.status.openDrowX && abs(mvPos.x) > abs(mvPos.y) * 2 && abs(mvPos.x) > minMove){
                                        HomeEvents.status.openDrowX = true
                                    }
                                    if(HomeEvents.status.openDrowX){
                                        onDelta(0f,pan.x)
                                    }
                                }
                            } while (points.any { it.pressed })

                            Log.d(TAG, "SlidingEnable: up")
                            if (boxTop != 0f) {
                                onDrawEnd(0f)
                                Handler().postDelayed({
                                    onDrawEnd(0f)
                                }, 200)
                            }

                            if (dragEnabled.value) {
                                dragEnabled.value = false
                                HomeEvents.status.openDrowX = false
                                Log.d(TAG, "SlidingEnable: close")
                            }
                            else if(HomeEvents.status.enableDrowUp){
                                //左右的距离大于上下距离的2倍 并且左右距离大于最小启动距离
                                if (abs(mvPos.x) > abs(mvPos.y) * 2 && abs(mvPos.x) > minMove) {
                                    HomeEvents.onDragHorizontal(mvPos.x)
                                }else if(abs(mvPos.x) < minMove &&  abs(mvPos.y)< minMove){
                                    //没有被子元素处理过
                                    if(points.any{ it.isConsumed}) {
                                        return@awaitPointerEventScope
                                    }
                                    if( HomeEvents.onPanEnd(mvPos)) return@awaitPointerEventScope

                                    val showMenuEvent = PageConf.homePage.ShowMenuEvent.getValue<Int>()
                                    if(showMenuEvent ==0){
                                        HomeEvents.onOpenMenu(mvPos)
                                    }else if(showMenuEvent==1){
                                        // 等待第二次点击或超时
                                        val secondDown = withTimeoutOrNull(300) { // 自定义超时时间（毫秒）
                                            awaitFirstDown(false)
                                        }
                                        if (secondDown != null) {
                                            if(showMenuEvent == 1)
                                                HomeEvents.onOpenMenu(mvPos)
                                        }
                                    }
                                }
                            }
                        }
                    }
                    //手指缩放事件
                    detectTransformGestures(
                        panZoomLock = true,
                        onGesture = { centroid, pan, zoom, rotation ->
                            scale *= zoom
                            m_rotation += rotation

                        }
                    )
                }
                .graphicsLayer(
                    scaleX = scale,
                    scaleY = scale,
                    rotationZ = m_rotation,
                )
                //        //拖拽事件
                //        .draggable(
                //            state = rememberDraggableState(onDelta = onDelta),
                //            Orientation.Vertical,
                ////            enabled = dragEnabled.value,
                //            //开始拖拽
                //            onDragStarted = { offset ->
                //                dragDistance = 0f
                //            },
                //            //拖拽结束
                //            onDragStopped = {
                //                onDrawEnd(it)
                //            }
                //        )
        ) {
            //展示页面为0或 尝试展示的页面为0 则展示分组页
            if (showPageIndex == 0 || tryShowPageVisables[0]) {
//                GroupInfoPage(scrollPercent)
                BookSearch(focusRequester) {
                    showPageIndex = 1
                    HomeEvents.status.openDrowUp = true
                }

                //SwitchMainPage(scrollPercent)
            } else {
//                HomeEvents.downMenuOpen = false;
//                if (showPageIndex == 2 || tryShowPageVisables[2]) {  //展示页面为2 或 尝试展示的页面为2 则展示主页选择页
//                  SwitchMainPage(scrollPercent)
//                }
            }
            //loading加载页
            if (showLoadingPage) {
                LoadingPage(scrollPercent.value * 3.33)
            }
            Box(
                content = contentBox,
                modifier = Modifier
                    .fillMaxSize()
                    .offset(y = px2dp(boxTop.toInt()),x=px2dp(boxLeft.toInt()))
                    .alpha(1 - scrollPercent.value)
            )
        }
    }
}
class SlidingEnableData(ct: Context,enabled: Boolean){

        /*** 上下滑动效果  */
        val fullHeight = with(ct) {
            resources.displayMetrics.heightPixels
        }
        //出现小程序页面的滚动高度
        val limitHight = fullHeight / 10
        //拖拽的长度
        var dragDistance by mutableStateOf(0F)
        //主页的top
        var boxTop by mutableStateOf(0F)
        var boxLeft by mutableStateOf(0F)
        //拖拽完成的百分比 0~1
        var scrollPercent =  mutableStateOf(0f)
        //当前显示的页面 (0 1 2)
        var showPageIndex by mutableStateOf(1)

        //显示加载页
        var showLoadingPage by mutableStateOf(false)
        //尝试展示的页面
        var tryShowPageVisables by mutableStateOf(arrayOf(false, false, false))
        val focusRequester= FocusRequester()
        init {
            HomeEvents.onBackBefore{
                val rt = showPageIndex!=0
                if(!rt) {
                    showPageIndex=1
                    scrollPercent.value=0f
                    boxTop = 0f
                }
                rt
            }
            // 动画实例
            HomeEvents.showMainPage = {
                MainScope().launch {
                    boxTop = 0f
                    showPageIndex = 1
                    tryShowPageVisables = arrayOf(false, false, false)
                    scrollPercent.value = 0f
                }
            }
        }


        //更新当前页面
        fun upPageIndex(relChange: Boolean = false) {
            var n = 0;
            when {
                //往上
                dragDistance < -5 -> n = 1
                //保持不变offset
                dragDistance < 5 -> n = 0
                //往下
                else -> n = -1
            }
            if (relChange) {
                showPageIndex += n
                showPageIndex = Math.max(Math.min(showPageIndex, 2), 0)
                tryShowPageVisables = arrayOf(false, false, false)
                if(viewMode in listOf(wordStudy,showArticle) ){
                    //保留上面的但是主要就是这里的两个操作 显示搜索框 当前不要切换
                    HomeEvents.searchTools.show(from = "dropDown");
                    showPageIndex = 1;
                }else{
                    HomeEvents.status.openDrowUp =false
                    focusRequester.requestFocus()
                }
            } else if (showPageIndex + n in (0..tryShowPageVisables.size - 1)) {
                tryShowPageVisables[showPageIndex + n] = true
            }
            Log.d(
                TAG,
                "DraggableGestureScreen end upPageIndex: $showPageIndex " + tryShowPageVisables.toList()
                    .joinToString(",")
            )
        }

        //分发给父容器
        val dispatch = NestedScrollDispatcher()

        val dragEnabled = mutableStateOf(false)

        var childTop = 0
        fun onDelta(it:Float,x: Float=0f)  {
            if(it==0f){
                boxLeft+=x
            }
            //滑动距离
            dragDistance += it
            if(boxTop==0f){
                if(Math.abs(dragDistance)>30) {
                    boxTop += it
                }
                return
            }
            if (dragDistance > 0 && dragDistance < limitHight) showLoadingPage = true
            //主页的top值
            boxTop += it

            //百分比
            val pre = Math.min(1f, abs(dragDistance) / (fullHeight/5))
            scrollPercent.value = if (showPageIndex == 1) pre else 1f - pre
        }
        val onDrawEnd :(y:Float)->Unit ={ offset ->
            childTop = 0
            Log.d(TAG, "DraggableGestureScreen end dragDistance: $dragDistance $offset ")
            val fHeight = fullHeight.toFloat()
            dragDistance += offset
            //如果拖拽的距离大于限制高度的3倍则切换
            if (abs(dragDistance) > limitHight) {
                upPageIndex(true)
            }
            dragDistance = 0f
//        MainScope().launch {
//            //动画修改主页的top值
//            Animatable(boxTop).animateTo(
//                when (showPageIndex) {
//                    0 -> fHeight
//                    1 -> 0f
//                    2 -> -fHeight
//                    else -> 0f
//                }
//            ) {
//                boxTop = value
//            }
//        }

            boxTop = when (showPageIndex) {
                0 -> fHeight-100
                1 -> 0f
                2 -> -fHeight
                else -> 0f
            }
            //重置参数值
            tryShowPageVisables = arrayOf(false, false, false)
            scrollPercent.value = if (showPageIndex == 1) 0f else 1f
            Log.d(TAG,"DraggableGestureScreen end showPageIndex: $showPageIndex $scrollPercent " + tryShowPageVisables)
        }
        val connection = object : NestedScrollConnection {
                //返回自身消费了的偏移量 从而控制子模块的滑动
                override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
                    val v = available.y.toInt()
                    //滑动开始之后内部滑动就不要进行了
                    if (enabled && boxTop * childTop <= 0) {
                        onDelta(available.y)
//                    dispatch.dispatchPreScroll(Offset(0f,available.y),NestedScrollSource.Drag)
                        Log.d("SwitchMainPage: ", "$available")
                        return available
                    }
                    return Offset.Zero;
//                return super.onPreScroll(available, source) ?: Offset.Zero
//                return available
                }

                override fun onPostScroll(
                    consumed: Offset,   //当前子组件消费的距离
                    available: Offset,  //当前父容器可以再次消费的剩余距离
                    source: NestedScrollSource
                ): Offset {
                    childTop += consumed.y.toInt()
                    //子组件滑动完成之后， 如果还有可用的距离，那么父组件就消费
                    if(enabled && consumed.y==0.0f && Math.abs(available.y)>0){
                        onDelta(available.y)
//                    dispatch.dispatchPostScroll(Offset(0f,0f),Offset(0f,available.y),NestedScrollSource.Drag)
                        Log.d("SwitchMainPage: ", "$consumed,$available")
                    }
                    return super.onPostScroll(consumed, available, source)
                }
            }

        var scale by mutableStateOf(1f)
        var m_rotation by mutableStateOf(0f)
    }